package com.recharge.service.impl;

import java.util.*;
import java.util.concurrent.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import com.baomidou.mybatisplus.annotation.SqlParser;
import com.recharge.common.util.*;
import com.recharge.core.entity.*;
import com.recharge.core.mapper.OrderCommitMapper;
import com.recharge.core.mapper.QcellcoreMapper;
import com.recharge.domain.vo.*;
import com.recharge.service.*;

import org.apache.commons.lang3.StringUtils;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;


import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.recharge.common.domain.PageDO;
import com.recharge.common.enums.ErrorCode;

import com.recharge.common.result.ResultDO;
import com.recharge.common.result.ResultSupport;
import com.recharge.core.mapper.OrderMapper;
import com.recharge.domain.query.OrderQueryDO;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import javax.annotation.PostConstruct;


/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author reagan
 * @since 2020-08-19
 */
@Service
public class OrderServiceImpl extends ServiceImpl<OrderMapper, OrderEntity> implements OrderService {

    private final int ORDER_SEND_NUMBER = 1000;

	@Autowired
	private RefundService refundService;

	@Autowired
	private MerchantService merchantService;

	@Autowired
	private GoodsService goodsService;

	@Autowired
	private ProviderOrderService providerOrderService;

	@Autowired
	private TransactionService transactionService;

	@Autowired
	private ProviderApiService providerApiService;

	@Autowired
	private OrderMapper orderMapper;

	@Autowired
	private OrderCommitMapper orderCommitMapper;

	@Autowired
	private QcellcoreMapper qcellcoreMapper;

	@Autowired
	private RouteFilterService routeFilterService;

	@Autowired
	private GoodsMerchantService goodsMerchantService;

	@Autowired
	MerchantAccountService merchantAccountService;

	@Autowired
	private CardVoucherService cardVoucherService;

	@Autowired
	private VoucherRecordService voucherRecordService;

	@Autowired
	private RechargeService rechargeService;

	@Autowired
	private RedisUtil redisUtil;

	@Value("${node.name}")
	private Integer nodeName;

	private Logger logger = LoggerFactory.getLogger(OrderServiceImpl.class);

	private ExecutorService executorService = null;

	@PostConstruct
	public void init() {

		executorService =  new ThreadPoolExecutor(10, 500,
				15,
				TimeUnit.SECONDS,
				new ArrayBlockingQueue<>(512),
				new ThreadPoolExecutor.DiscardPolicy());

	}


	@Override
	public ResultDO add(OrderDO domain) {

		OrderEntity entity = new OrderEntity();

		//创建订单
		int res = -1;
		ResultDO result = BeanUtilsExtends.copy(entity, domain);
		if (!result.isSuccess()) {
			//logger.info("error code：" + result.getErrorCode().getCode() + " msg" + result.getErrorCode().getMsg());
			return result;
		}
		entity.setNodeName(nodeName);
		entity.setModifiDate(Calendar.getInstance().getTime());
		try {
			res = orderMapper.insert(entity);
		} catch (Exception e) {
			result.setSuccess(false);
			result.setErrorCode(ErrorCode.SYSTEM_EXCEPTION);
			//logger.info("error code：" + ErrorCode.SYSTEM_EXCEPTION.getCode() + " msg" + ErrorCode.SYSTEM_EXCEPTION.getMsg());
			return result;
		}


		if(res <= 0) {
			result.setSuccess(false);
			result.setErrorCode(ErrorCode.ORDER_CREATE_ERROR);
			//logger.info("error code：" + ErrorCode.ORDER_CREATE_ERROR.getCode() + " msg" + ErrorCode.ORDER_CREATE_ERROR.getMsg());
			return result;
		}


		//logger.info("add order end time:" + (System.currentTimeMillis() - beginTime));
		return result;
	}


	@Override
	public ResultDO edit(OrderDO domain) {

		OrderEntity entity = new OrderEntity();

		ResultDO result = BeanUtilsExtends.copy(entity, domain);
		if (!result.isSuccess()) {
			//logger.info("error code：" + result.getErrorCode().getCode() + " msg" + result.getErrorCode().getMsg());
			return result;
		}

		entity.setModifiDate(Calendar.getInstance().getTime());

		boolean res = false;
		try {
			res = this.updateById(entity);
		} catch (Exception e) {
			result.setSuccess(false);
			result.setErrorCode(ErrorCode.SYSTEM_EXCEPTION);
			//logger.info("error code：" + ErrorCode.SYSTEM_EXCEPTION.getCode() + " msg" + ErrorCode.SYSTEM_EXCEPTION.getMsg());
			return result;
		}

		//判断r的值是否小于0.如果小于0 就代表添加失败
		if(!res) {
			result.setSuccess(false);
			result.setErrorCode(ErrorCode.MERCHANT_EDIT_ACCOUNT_ERROR);
			//logger.info("error code：" + ErrorCode.MERCHANT_EDIT_ACCOUNT_ERROR.getCode() + " msg" + ErrorCode.MERCHANT_EDIT_ACCOUNT_ERROR.getMsg());
			return result;
		}

		return result;
	}

	@Override
	public ResultDO saveUpdate(OrderDO domain) {

		OrderEntity entity = new OrderEntity();

		ResultDO result = BeanUtilsExtends.copy(entity, domain);
		if (!result.isSuccess()) {
			//logger.info("error code：" + result.getErrorCode().getCode() + " msg" + result.getErrorCode().getMsg());
			return result;
		}

		entity.setModifiDate(Calendar.getInstance().getTime());
		entity.setNodeName(nodeName);
		int res = -1;
		try {
			res = this.baseMapper.deleteById(entity.getId());
		} catch (Exception e) {
			result.setSuccess(false);
			result.setErrorCode(ErrorCode.SYSTEM_EXCEPTION);
			//logger.info("error code：" + ErrorCode.SYSTEM_EXCEPTION.getCode() + " msg" + ErrorCode.SYSTEM_EXCEPTION.getMsg());
			return result;
		}

		//判断r的值是否小于0.如果小于0 就代表添加失败
		if(res <= 0) {
			result.setSuccess(false);
			result.setErrorCode(ErrorCode.MERCHANT_EDIT_ACCOUNT_ERROR);
			//logger.info("error code：" + ErrorCode.MERCHANT_EDIT_ACCOUNT_ERROR.getCode() + " msg" + ErrorCode.MERCHANT_EDIT_ACCOUNT_ERROR.getMsg());
			return result;
		}

		res = -1;
		try {
			res = this.baseMapper.insert(entity);
		} catch (Exception e) {
			result.setSuccess(false);
			result.setErrorCode(ErrorCode.SYSTEM_EXCEPTION);
			//logger.info("error code：" + ErrorCode.SYSTEM_EXCEPTION.getCode() + " msg" + ErrorCode.SYSTEM_EXCEPTION.getMsg());
			return result;
		}

		//判断r的值是否小于0.如果小于0 就代表添加失败
		if(res <= 0) {
			result.setSuccess(false);
			result.setErrorCode(ErrorCode.MERCHANT_EDIT_ACCOUNT_ERROR);
			//logger.info("error code：" + ErrorCode.MERCHANT_EDIT_ACCOUNT_ERROR.getCode() + " msg" + ErrorCode.MERCHANT_EDIT_ACCOUNT_ERROR.getMsg());
			return result;
		}

		return result;
	}

	public ResultDO resettingOrder(OrderDO domain) {
		//logger.info("重置订单设置订单重置" + domain.getRetryStatus() + ":" + domain.getId());
		ResultDO result = new ResultSupport();

		OrderEntity entity = new OrderEntity();

		entity.setId(domain.getId());
		entity.setStatus(Constant.RECHARGE_ORDER_STATUS_1);
		entity.setRetryStatus(domain.getRetryStatus());

		boolean res = false;

		try {
			res = this.updateById(entity);
		} catch (Exception e) {
			e.printStackTrace();
			result.setSuccess(false);
			result.setErrorCode(ErrorCode.SYSTEM_EXCEPTION);
			//logger.info("error code：" + ErrorCode.SYSTEM_EXCEPTION.getCode() + " msg" + ErrorCode.SYSTEM_EXCEPTION.getMsg());
			return result;
		}

		//判断r的值是否小于0.如果小于0 就代表添加失败
		if(!res) {
			result.setSuccess(false);
			result.setErrorCode(ErrorCode.ORDER_EDIT_ERROR);
			//logger.info("订单重置失败");
			//logger.info("error code：" + ErrorCode.ORDER_EDIT_ERROR.getCode() + " msg" + ErrorCode.MERCHANT_EDIT_ACCOUNT_ERROR.getMsg());
			return result;
		}

		return result;
	}


	private ResultDO getOrderGoodsChannel(OrderDO domain) {

		ResultDO result = goodsService.getGoodsChannel(domain);
		if(!result.isSuccess()) {
			//logger.info("订单去查找相应通道失败");
			return result;
		}

		List<GoodsChannelDO> goodsChannelArray = (List<GoodsChannelDO>) result.getModel(ResultDO.FIRST_MODEL_KEY);

		List<GoodsChannelDO> goodsChannels = new ArrayList<>();

		goodsChannels.addAll(goodsChannelArray);

		if(domain.getRetryStatus() == Constant.ORDER_RETRY_STATUS_1) {
			//logger.info("重试所有的通道");
		}
		if(domain.getRetryStatus() == Constant.ORDER_RETRY_STATUS_2) {
			//logger.info("重试当前的通道");
			boolean is = false;
			goodsChannels.clear();
			for(GoodsChannelDO goodsChannelDO : goodsChannelArray) {
				if(goodsChannelDO.getProviderId().equals(domain.getProviderId())) {
					//logger.info("之前使用了该通道就从这里开始");
					is = true;
				}
				if(is) {
					goodsChannels.add(goodsChannelDO);
				}
			}
		}
		if(domain.getRetryStatus() == Constant.ORDER_RETRY_STATUS_3) {
			//logger.info("重试当前的通道的下一个通道");
			boolean is = false;
			goodsChannels.clear();
			for(GoodsChannelDO goodsChannelDO : goodsChannelArray) {
				if(goodsChannelDO.getProviderId().equals(domain.getProviderId())) {
					//logger.info("之前使用了该通道就从这里的下一个开始");
					is = true;
					continue;
				}
				if(is) {
					goodsChannels.add(goodsChannelDO);
				}
			}
		}

		int prioritySum = 0;
		int providerMethod = 0;
		for (GoodsChannelDO goodsChannelDO : goodsChannels) {
			prioritySum += goodsChannelDO.getPriority();
			if(goodsChannelDO.getProviderMethod() != null) {
				providerMethod = goodsChannelDO.getProviderMethod();
			}
		}
		result.setModel(ResultDO.FIRST_MODEL_KEY, goodsChannels);
		result.setModel(ResultDO.SECOND_MODEL_KEY, prioritySum);
		result.setModel(ResultDO.THIRD_MODEL_KEY, providerMethod);
		return result;
	}


	public void exec(OrderDO orderDO) throws Exception {

		long beginTime = System.currentTimeMillis();
		logger.info("开辟线程处理订单号为:" + orderDO.getOrderNo() + " 线程ID为：" + Thread.currentThread().getId());
		String serialNumber = SnowflakeIdWorker.getNo();
		//logger.info("订单号为:" + entity.getOrderNo() + " 生成的唯一流水号:" + serialNumber);
		boolean isCallback = false;
		int callbackCode = 0;
		String message = "";

		orderDO.setProviderSerialNumber(serialNumber);
		boolean isException = false;
		beginTime = System.currentTimeMillis();
		TransactionDO transactionDO = new TransactionDO();
		GoodsDO goodsDO = null;
		boolean isError = false;

		ResultDO result = goodsService.getGoodsByGoodsNo(orderDO.getGoodsNo(), orderDO.getAmount(), orderDO.getRechargeNumber());
		if(!result.isSuccess()) {
			isException = true;
			isError = true;
			callbackCode = result.getErrorCode().getCode();
			message = result.getErrorCode().getMsg();
			isCallback = true;
		} else {
			goodsDO = (GoodsDO) result.getModel(ResultDO.FIRST_MODEL_KEY);

			orderDO.setTitle(goodsDO.getTitle());
			orderDO.setGoodsId(goodsDO.getId());
			orderDO.setProvinceName(goodsDO.getProvinceName());
			orderDO.setCityName(goodsDO.getCityName());
			orderDO.setServiceProvider(goodsDO.getServiceProvider());
			result = orderPay(orderDO);
			if (!result.isSuccess()) {
				logger.info("没有和下游的价格进行关联或者订单扣除余额失败");
				isException = true;
				isError = true;
				callbackCode = result.getErrorCode().getCode();
				message = result.getErrorCode().getMsg();
				isCallback = true;
			} else {
				Long amount = (Long) result.getModel(ResultDO.FIRST_MODEL_KEY);
				Float agentDiscount = (Float) result.getModel(ResultDO.SECOND_MODEL_KEY);
				Long beforeBalance = (Long) result.getModel(ResultDO.THIRD_MODEL_KEY);
				Long afterBalance = (Long) result.getModel(ResultDO.FOURTH_MODEL_KEY);

				transactionDO.setAmount(amount);
				transactionDO.setBeforeBalance(beforeBalance);
				transactionDO.setBalance(afterBalance);
				orderDO.setAgentDiscount(agentDiscount);
			}
		}

		List<GoodsChannelDO> goodsChannels = null;
		int prioritySum = 0;
		int providerMethod = 0;
		if(!isError) {
			result = getOrderGoodsChannel(orderDO);
			if (!result.isSuccess()) {
				//logger.info("没有和下游的价格进行关联或者订单扣除余额失败");
				isException = true;
				callbackCode = result.getErrorCode().getCode();
				message = result.getErrorCode().getMsg();
				isCallback = true;
			} else {
				goodsChannels = (List<GoodsChannelDO>) result.getModel(ResultDO.FIRST_MODEL_KEY);
				prioritySum = (int) result.getModel(ResultDO.SECOND_MODEL_KEY);
				providerMethod = (int) result.getModel(ResultDO.THIRD_MODEL_KEY);

				if(goodsChannels.size() == 0) {
					isException = true;
					callbackCode = ErrorCode.API_GOODS_PROVIDER_FAIL.getCode();
					message = ErrorCode.API_GOODS_PROVIDER_FAIL.getMsg();
					isCallback = true;
				}
			}
		}
		if(!isException) {
			//logger.info("当前通道总数 Channels size ：" + goodsChannels.size());
			if (providerMethod == Constant.PROVIDER_METHOD_1) {
				//logger.info("走卡密供应方式");
				//供应方式为1的时候获取卡密
				result = cardVoucherService.getCardByGoodsNo(orderDO.getGoodsNo());
				List<CardVoucherDO> cardVoucheres = (List<CardVoucherDO>) result.getModel(ResultDO.FIRST_MODEL_KEY);
				for (CardVoucherDO cardVoucherDO : cardVoucheres) {
					int cardStatus = 0;
					orderDO.setCardNo(cardVoucherDO.getVoucherNo());
					orderDO.setCardPassword(cardVoucherDO.getVoucherPassword());
					result = send(orderDO, goodsChannels, transactionDO, prioritySum, serialNumber);
					if (!result.isSuccess()) {
						callbackCode = ErrorCode.API_GOODS_PROVIDER_FAIL.getCode();
						message = result.getErrorCode().getMsg();
						isCallback = true;
						if (result.getErrorCode() == ErrorCode.API_GOODS_PROVIDER_FAIL) {
							//全部通道失败供应失败但是卡密不会核销
							break;
						} else if (result.getErrorCode() == ErrorCode.CARD_VOUCHER_RECHARGE_INVALID) {
							//卡密失败核销卡
							cardStatus = Constant.CARDVOUCH_STATUS_INVALID;
							cardVoucherService.editStatus(orderDO.getCardNo(), cardStatus);
						}
					} else {
						cardStatus = Constant.CARDVOUCH_STATUS_PROCESS;
						cardVoucherService.editStatus(orderDO.getCardNo(), cardStatus);
						break;
					}
				}

			} else if (providerMethod == Constant.PROVIDER_METHOD_2) {
				//logger.info("走直充供应方式");
				result = send(orderDO, goodsChannels, transactionDO, prioritySum, serialNumber);
				if (!result.isSuccess()) {
					callbackCode = result.getErrorCode().getCode();
					message = result.getErrorCode().getMsg();
					isCallback = true;
				}
			}
			orderDO = (OrderDO) result.getModel(ResultDO.FIRST_MODEL_KEY);
			transactionDO = (TransactionDO) result.getModel(ResultDO.SECOND_MODEL_KEY);

			if (orderDO.getStatus() == Constant.RECHARGE_ORDER_STATUS_4) {
				RefundDO refundDO = new RefundDO();
				refundDO.setMerchantNo(orderDO.getMerchantNo());
				refundDO.setMerchantId(orderDO.getMerchantId());
				refundDO.setAmount(Double.valueOf(String.valueOf(ArithUtils.mul(Double.parseDouble(String.valueOf(orderDO.getAmount())), Double.parseDouble(String.valueOf(orderDO.getAgentDiscount()))))).longValue());
				refundDO.setGoodsTitle(orderDO.getTitle());
				refundDO.setMerchantName(orderDO.getMerchantName());
				refundDO.setType(Constant.REFUND_TYPE_AUTO);
				refundDO.setStatus(Constant.REFUND_STATUS_1);
				refundService.submit(refundDO);
			}
		} else {
			transactionDO.setStatus(Constant.TRANSACTION_STATUS_0);
			orderDO.setProviderCallbackInfo(message);
			orderDO.setStatus(Constant.RECHARGE_ORDER_STATUS_4);
		}
		orderDO.setProcessTime(System.currentTimeMillis() - beginTime);
		if (orderDO.getRetryStatus() == Constant.ORDER_RETRY_STATUS_0) {
			updateStatus(transactionDO, orderDO);
		}

		if (isCallback) {
			//logger.info("订单出现错误写回调单");
			merchantService.callback(
					orderDO.getMerchantSerialNumber(),
					orderDO.getOrderNo(),
					orderDO.getRechargeNumber(),
					"",
					callbackCode,
					message,
					orderDO.getCallback());
		}
		//logger.info(Thread.currentThread().getId() + " 当前计数器：" + counter);
		logger.info(" ================= 处理一个订单耗时" + orderDO.getOrderNo() + " : " + (System.currentTimeMillis() - beginTime) + "======================");
		transactionDO = null;
		orderDO =null;
	}

	private ResultDO updateStatus(TransactionDO transactionDO, OrderDO orderDO) {
		transactionDO.setGoodsName(orderDO.getTitle());
		transactionDO.setIdentifierNo(orderDO.getOrderNo());
		transactionDO.setMerchantNo(orderDO.getMerchantNo());
		transactionDO.setType(Constant.TRANSACTION_TYPE_3);
		transactionDO.setAmountType(Constant.EXPEND);
		String transactionNo = SnowflakeIdWorker.getNo();
		transactionDO.setTransactionNo(transactionNo);
		ResultDO result = transactionService.add(transactionDO);
		transactionDO = (TransactionDO) result.getModel(ResultDO.FIRST_MODEL_KEY);

		orderDO.setProvideQuartity(1);
		orderDO.setTransactionNo(transactionNo);
		orderDO.setTransactionId(transactionDO.getId());

		OrderEntity entity = new OrderEntity();
		BeanUtilsExtends.copy(entity, orderDO);
		entity.setNodeName(nodeName);
		entity.setModifiDate(Calendar.getInstance().getTime());

		orderMapper.insert(entity);

		logger.info("redis order" + orderDO);
		//requestOrderQueue.push(orderDO);
		//redisUtil.set(Constant.ORDER_INFO + ":" + orderDO.getOrderNo(), orderDO);
		logger.info(orderDO.getOrderNo() + " 更新订单的充值结果：" + orderDO.getStatus());
		return result;
	}


	private ResultDO send(OrderDO orderDO, List<GoodsChannelDO> goodsChannels, TransactionDO transactionDO, int prioritySum, String serialNumber) {
		GoodsChannelDO channel = null;
		int code = 0;
		ResultDO result = new ResultSupport();
		for (int index = 0; index < goodsChannels.size(); index++) {
			channel = goodsChannels.get(index);
			//logger.info("上游供应商编号：" + channel.getProviderNo() + "上游供应名称：" + channel.getProviderName());

			channel.setProviderSerialNumber(serialNumber);
			orderDO.setGoodsChannelDO(channel);
			orderDO.setProviderId(channel.getProviderId());
			orderDO.setProviderNo(channel.getProviderNo());
			orderDO.setProviderName(channel.getProviderName());
			orderDO.setCostDiscount(channel.getCostDiscount());

			int currentBatchCount = 0;

			if(isCommit(orderDO, channel)) {
				if(StringUtils.isNotEmpty(orderDO.getCardNo()) && StringUtils.isNotEmpty(orderDO.getCardPassword())) {
					channel.setCardNo(orderDO.getCardNo());
					channel.setCardPassword(orderDO.getCardPassword());
				}
				if (prioritySum != 0) {
					//logger.info("通道当中有权重值走权重计算");
					//result = priority(channel, prioritySum, orderDO.getGoodsNo(), orderDO.getGoodsSize());
					if (result.isSuccess()) {
						//logger.info("上游供应名称：" + channel.getProviderName() + " 通道量未满");
						code = call(orderDO);
						currentBatchCount = (int) result.getModel(ResultDO.FIRST_MODEL_KEY);
					} else {
						logger.info("上游供应名称：" + channel.getProviderName() + "通道量已满跳到下一条通道");
						redisUtil.set(nodeName + orderDO.getGoodsNo() + channel.getProviderId(), currentBatchCount);
						continue;
					}
				} else {
					logger.info("通道当中没有权重值");
					code = call(orderDO);
				}
			}

			if (code == Constant.BUSINESS_RECHARGE_RETURN_STATUS_SUCCESS
					|| code == Constant.BUSINESS_RECHARGE_RETURN_STATUS_OUT_TIME) {
				//logger.info("订单号：" + orderDO.getOrderNo() + "已经提交成功");
				orderDO.setStatus(Constant.RECHARGE_ORDER_STATUS_5);
				if (code == Constant.BUSINESS_RECHARGE_RETURN_STATUS_OUT_TIME) {
					//logger.info("订单号：" + orderDO.getOrderNo() + "已经提交未确定");
					orderDO.setStatus(Constant.RECHARGE_ORDER_STATUS_7);
				}
				if (prioritySum != 0) {
					redisUtil.set(nodeName + orderDO.getGoodsNo() + channel.getProviderId(), currentBatchCount);
				}
				transactionDO.setStatus(Constant.TRANSACTION_STATUS_1);
				result.setModel(ResultDO.FIRST_MODEL_KEY, orderDO);
				result.setModel(ResultDO.SECOND_MODEL_KEY, transactionDO);
				return result;
			} else if (code == Constant.BUSINESS_RECHARGE_RETURN_STATUS_FAIL) {
				//logger.info("订单号：" + orderDO.getOrderNo() + "调用上游接口失败使用下一个接口");
				orderDO.setStatus(Constant.RECHARGE_ORDER_STATUS_4);
				transactionDO.setStatus(Constant.TRANSACTION_STATUS_0);
			} else if(code == Constant.BUSINESS_RECHARGE_RETURN_STATUS_CARD_INVALID){
				//logger.info("订单号：" + orderDO.getOrderNo() + "卡密无效");
				result.setSuccess(false);
				result.setErrorCode(ErrorCode.CARD_VOUCHER_RECHARGE_INVALID);
				result.setModel(ResultDO.FIRST_MODEL_KEY, orderDO);
				result.setModel(ResultDO.SECOND_MODEL_KEY, transactionDO);
				return result;
			} else {
				//logger.info("订单号：" + orderDO.getOrderNo() + "没有供应商接口");
				orderDO.setStatus(Constant.RECHARGE_ORDER_STATUS_4);
				transactionDO.setStatus(Constant.TRANSACTION_STATUS_0);
			}
			logger.info("调用上游接口返回的code：" + code);
		}
		result.setSuccess(false);
		result.setErrorCode(ErrorCode.API_GOODS_PROVIDER_FAIL);
		result.setModel(ResultDO.FIRST_MODEL_KEY, orderDO);
		result.setModel(ResultDO.SECOND_MODEL_KEY, transactionDO);
		return result;
	}

	private boolean isCommit(OrderDO orderDO, GoodsChannelDO channel) {
		//路由黑名单
		ResultDO result = routeFilterService.getRouterByProviderAndMerchantId(channel.getProviderId(), orderDO.getMerchantId(), 1);
		if (!result.isSuccess()) {
			logger.info("通道是该商品黑名单");
			return false;
		}

		if(orderDO.getRetryStatus() == Constant.ORDER_RETRY_STATUS_0) {
			//查询是否改订单已经调用该通道并且失败
			result = providerOrderService.getProviderOrderFail(orderDO.getOrderNo(), channel.getProviderId());
			if (!result.isSuccess()) {
				logger.info("通道有失败的供应单");
				return false;
			}
		}
		return true;
	}

	private ResultDO orderPay(OrderDO orderDO) {
		Long amount = 0L;
		Long beforeBalance = 0L;
		Long afterBalance = 0L;
		Float agentDiscount = 0.0F;

		ResultDO result = goodsMerchantService.getGoodsMerchantDiscount(orderDO.getGoodsId(), orderDO.getMerchantId());
		if (!result.isSuccess()) {
			logger.info("商品与代理商价格关联失败");
			//商品与下游价格关联失败
			result.setErrorCode(ErrorCode.API_MERCHANET_GOODS_ERROR);
			return result;
		}

		agentDiscount = (Float) result.getModel(ResultDO.FIRST_MODEL_KEY);
		amount = (long) ArithUtils.mul((double) orderDO.getAmount(), Double.parseDouble(agentDiscount.toString()));

		result = merchantAccountService.editBalance(orderDO.getMerchantId(),  -amount);

		beforeBalance = (Long) result.getModel(ResultDO.FIRST_MODEL_KEY);
		afterBalance = (Long) result.getModel(ResultDO.SECOND_MODEL_KEY);
		if (!result.isSuccess()) {
			logger.info("订单支付扣款失败");
			result.setErrorCode(ErrorCode.API_USER_BALANCE_STATUS_ERROR);
			return result;
		}

		result.setModel(ResultDO.FIRST_MODEL_KEY, amount);
		result.setModel(ResultDO.SECOND_MODEL_KEY, agentDiscount);
		result.setModel(ResultDO.THIRD_MODEL_KEY, beforeBalance);
		result.setModel(ResultDO.FOURTH_MODEL_KEY, afterBalance);
		return result;
	}


	private ResultDO priority(GoodsChannelDO goodsChannelDO, int prioritySum, int goodsNo, int orderSize) {
		ResultDO result = new ResultSupport();
		Integer currentBatchCount = null;
		logger.info("当前通道：" + goodsChannelDO.getProviderName() + " 权重值为：" + goodsChannelDO.getPriority() + " prioritySum:" + prioritySum);
		//该产品下面权重不为0的通道进行权重计算

		double ratio = (goodsChannelDO.getPriority().intValue() * 0.1) / (prioritySum * 0.1);

		logger.info("计算出来的权重量：" + ratio);
		//得到当前通道已发送数量
		currentBatchCount = (Integer) redisUtil.get(nodeName + goodsNo + goodsChannelDO.getProviderId());
		if (currentBatchCount == null) {
			currentBatchCount = 0;
			redisUtil.set(nodeName + goodsNo + goodsChannelDO.getProviderId(), currentBatchCount);
		}
		logger.info("当前通道：" + goodsChannelDO.getProviderName() + " 已经发送：" + currentBatchCount);
		//权重计算得到可以发送量
		int orderCount = (int) Math.round(orderSize * ratio);
		logger.info("当前通道：" + goodsChannelDO.getProviderName() + " 分配的量为：" + orderCount);
		//发送数量大于本批次可以发送数量时跳过该通道走下一个通道
		if (currentBatchCount >= orderCount) {
			logger.info("当前通道：" + goodsChannelDO.getProviderName() + "已满");
			result.setSuccess(false);
			result.setModel(ResultDO.FIRST_MODEL_KEY, currentBatchCount);
		} else {
			currentBatchCount++;
			result.setModel(ResultDO.FIRST_MODEL_KEY, currentBatchCount);
		}
		return result;
	}

	/*private boolean isCommitByThreshold(GoodsChannelDO goodsChannelDO) {
		//阀值
		int threshold = (int) redisUtil.get(Constant.PROVIDER_THRESHOLD  + ":" +  goodsChannelDO.getProviderId());
		//当前发送量初始化为0
		int currentSendCount = (int) redisUtil.get(Constant.PROVIDER_CURRENT_SEND_COUNT  + ":" +  goodsChannelDO.getProviderId());

		Long lastTime = Long.valueOf(redisUtil.get(Constant.PROVIDER_LAST_TIME  + ":" +  goodsChannelDO.getProviderId()).toString());
		if(lastTime == 0) {
			lastTime = System.currentTimeMillis();
			redisUtil.set(Constant.PROVIDER_LAST_TIME  + ":" +  goodsChannelDO.getProviderId(), lastTime);
		}

		if(threshold != 0) {
			//阀值不为空的时候24小时内进行阀值控制
			if ((System.currentTimeMillis() - lastTime) < 86400000L) {
				if(currentSendCount <= threshold) {
					currentSendCount++;
					redisUtil.set(Constant.PROVIDER_CURRENT_SEND_COUNT  + ":" +  goodsChannelDO.getProviderId(), currentSendCount);
					return true;
				} else {
					//大于阀值跳过该通道
					return false;
				}
			} else {
				return true;
			}
		} else {
			return true;
		}
	}*/

	private int call(OrderDO domain) {

		int status = 0;
		int code = 0;
		String message = "";
		boolean isWriter = true;
		long providerTime = System.currentTimeMillis();
		ResultDO result = new ResultSupport();

		GoodsChannelDO goodsChannelDO = domain.getGoodsChannelDO();
		logger.info("当前供应商：" + goodsChannelDO.getProviderName());
		goodsChannelDO.setAmount(domain.getAmount());
		goodsChannelDO.setOrderNo(domain.getOrderNo());
		goodsChannelDO.setServiceProvider(domain.getServiceProvider());
		//当前发送量小于阀值时可以继续发送
		try {
			long beginTime = System.currentTimeMillis();
			result = providerApiService.commitOrder(goodsChannelDO);
			logger.info("---------------发送HTTP请求返回用时"  + domain.getOrderNo() + " : " + (System.currentTimeMillis() - beginTime));
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			//code = Constant.BUSINESS_RECHARGE_RETURN_STATUS_FAIL;
			//message = "test";
			code = (int) result.getModel(ResultDO.FIRST_MODEL_KEY);
			message = (String) result.getModel(ResultDO.SECOND_MODEL_KEY);
		}

		int isOver = Constant.PROVIDER_ORDER_IS_OVER_0;
		if (code == Constant.BUSINESS_RECHARGE_RETURN_STATUS_SUCCESS) {
			status = Constant.PROVIDER_ORDER_STATUS_3;
		} else if (code == Constant.BUSINESS_RECHARGE_RETURN_STATUS_OUT_TIME) {
			status = Constant.PROVIDER_ORDER_STATUS_4;
		} else if (code == Constant.BUSINESS_RECHARGE_RETURN_STATUS_FAIL) {
			isOver = Constant.PROVIDER_ORDER_IS_OVER_1;
			status = Constant.PROVIDER_ORDER_STATUS_fail;
		} else if(code == Constant.BUSINESS_RECHARGE_RETURN_STATUS_CARD_INVALID) {
			//卡密无效不写供应单
			isWriter = false;
		}

		if(isWriter) {
			ProviderOrderDO providerOrder = new ProviderOrderDO();
			providerOrder.setOrderId(domain.getId());
			providerOrder.setOrderNo(domain.getOrderNo());
			providerOrder.setProviderId(goodsChannelDO.getProviderId());
			providerOrder.setProviderNo(goodsChannelDO.getProviderNo());
			providerOrder.setGoodsId(domain.getGoodsId());
			providerOrder.setGoodsNo(domain.getGoodsNo());
			providerOrder.setProviderMethod(goodsChannelDO.getProviderMethod());
			providerOrder.setCardVoucherNo(goodsChannelDO.getCardNo());
			providerOrder.setGoodsName(domain.getTitle());
			providerOrder.setMerchantId(domain.getMerchantId());
			providerOrder.setServiceProvider(domain.getServiceProvider());
			providerOrder.setMerchantNo(domain.getMerchantNo());
			providerOrder.setProviderName(goodsChannelDO.getProviderName());
			providerOrder.setMerchantName(domain.getMerchantName());
			providerOrder.setAgentDiscount(domain.getAgentDiscount());
			providerOrder.setSerialNumber(domain.getProviderSerialNumber());
			providerOrder.setRechargeNumber(domain.getRechargeNumber());
			providerOrder.setOrderDate(domain.getCreateDate());
			providerOrder.setAmount(domain.getAmount());
			providerOrder.setProvinceName(domain.getProvinceName());
			providerOrder.setCityName(domain.getCityName());
			providerOrder.setProcessTime(System.currentTimeMillis() - providerTime);
			providerOrder.setCostDiscount(goodsChannelDO.getCostDiscount());//.setCostAmount((long) (goodsChannelDO.getCostDiscount() * domain.getAmount()));
			providerOrder.setIsManual(Constant.MANUAL_PROVIDER_ORDER_STATUS_0);
			providerOrder.setIsRemedy(Constant.REMEDY_PROVIDER_ORDER_STATUS_0);
			providerOrder.setIsOver(isOver);
			providerOrder.setStatus(status);
			providerOrder.setRemark(message);
			providerOrderService.add(providerOrder);
		}

		logger.info("订单提交上游结果 status:" + status + " code:" + code);
		return code;
	}


	@Override
	public ResultDO selectListByIds(List<String> orderIdList) {

		ResultDO result = new ResultSupport();;

		if(orderIdList == null || orderIdList.isEmpty()){
			result.setSuccess(false);
			result.setErrorCode(ErrorCode.SYSTEM_EXCEPTION);
			logger.info("error code：" + ErrorCode.SYSTEM_EXCEPTION.getCode() + " msg" + ErrorCode.SYSTEM_EXCEPTION.getMsg());
			return result;
		}

		List<OrderEntity> orderList = null;
		try {
			orderList = this.listByIds(orderIdList);
		} catch (Exception e) {
			result.setSuccess(false);
			result.setErrorCode(ErrorCode.SYSTEM_EXCEPTION);
			logger.info("error code：" + ErrorCode.SYSTEM_EXCEPTION.getCode() + " msg" + ErrorCode.SYSTEM_EXCEPTION.getMsg());
			return result;
		}
		if(orderList == null || orderList.size() <=0){
			result.setSuccess(false);
			result.setErrorCode(ErrorCode.SYSTEM_EXCEPTION);
			logger.info("error code：" + ErrorCode.SYSTEM_EXCEPTION.getCode() + " msg" + ErrorCode.SYSTEM_EXCEPTION.getMsg());
			return result;
		}
		List<OrderDO> domainList = getDomainList(orderList);
		result.setModel(ResultDO.FIRST_MODEL_KEY, domainList);
		return result;
	}

	public ResultDO getRechagerStatusOrder(String orderNo) {
		ResultDO result = new ResultSupport();
		OrderEntity orderEntity = null;
		QueryWrapper<OrderEntity> wrapper = new QueryWrapper<>();
		wrapper.and(w->
				w.eq("order_no", orderNo)
						.eq("status", 5)
						.or()
						.eq("order_no", orderNo)
						.eq("status", 7));

		try {
			orderEntity = orderMapper.selectOne(wrapper);

		} catch (Exception e) {
			e.printStackTrace();
			result.setSuccess(false);
			result.setErrorCode(ErrorCode.SYSTEM_EXCEPTION);
			logger.info("error code：" + ErrorCode.SYSTEM_EXCEPTION.getCode() + " msg" + ErrorCode.SYSTEM_EXCEPTION.getMsg());
			return result;
		}

		if(orderEntity == null) {
			result.setSuccess(false);
			return result;
		}
		OrderDO order = getDomain(orderEntity);
		result.setModel(ResultDO.FIRST_MODEL_KEY, order);
		return result;
	}

	@Override
	public ResultDO editStatus(OrderDO order) {
		logger.info("回调更新订单状态:" + order.getOrderNo() + " Statu=" + order.getStatus() + " ProviderCallbackStatus=" + order.getProviderCallbackStatus() + " VoucherNo=" + order.getVoucherNo());

		ResultDO result = transactionService.get(order.getTransactionId());

		TransactionDO transactionDO = (TransactionDO) result.getModel(ResultDO.FIRST_MODEL_KEY);
		transactionDO.setEndDate(Calendar.getInstance().getTime());

		int transactionStatus = Constant.TRANSACTION_STATUS_0;;
		if(Constant.RECHARGE_ORDER_STATUS_4 == order.getStatus()) {
			RefundDO refundDO = new RefundDO();
			refundDO.setMerchantNo(order.getMerchantNo());
			refundDO.setMerchantId(order.getMerchantId());
			refundDO.setAmount(Double.valueOf(String.valueOf(ArithUtils.mul(Double.parseDouble(String.valueOf(order.getAmount())), Double.parseDouble(String.valueOf(order.getAgentDiscount()))))).longValue());
			refundDO.setGoodsTitle(order.getTitle());
			refundDO.setMerchantName(order.getMerchantName());
			refundDO.setType(Constant.REFUND_TYPE_AUTO);
			refundDO.setStatus(Constant.REFUND_STATUS_1);
			refundService.submit(refundDO);
		} else if(Constant.RECHARGE_ORDER_STATUS_3 == order.getStatus().intValue()) {
			transactionStatus = Constant.TRANSACTION_STATUS_1;
		}
		transactionDO.setStatus(transactionStatus);
		transactionService.saveUpdate(transactionDO);
		saveUpdate(order);
		result.setModel(ResultDO.FIRST_MODEL_KEY, order);
		return result;
	}

	public ResultDO get(String id) {

		ResultDO result = new ResultSupport();
		OrderEntity entity = null;

		try {
			entity = this.getById(id);
		} catch(Exception e) {
			result.setSuccess(false);
			result.setErrorCode(ErrorCode.SYSTEM_EXCEPTION);
			logger.info("error code：" + ErrorCode.SYSTEM_EXCEPTION.getCode() + " msg" + ErrorCode.SYSTEM_EXCEPTION.getMsg());
			return result;
		}

		OrderDO domain = getDomain(entity);

		result.setModel(ResultDO.FIRST_MODEL_KEY, domain);

		return result;
	}

	public ResultDO getByMerchantSerialNumber(String serialNumber) {
		logger.info("MerchantSerialNumber:" + serialNumber);
		ResultDO result = new ResultSupport();
		OrderEntity entity = null;

		try {
			entity = this.baseMapper.selectOne(Wrappers.<OrderEntity>lambdaQuery().eq(OrderEntity::getMerchantSerialNumber, serialNumber));
		} catch(Exception e) {
			result.setSuccess(false);
			result.setErrorCode(ErrorCode.SYSTEM_EXCEPTION);
			logger.info("error code：" + ErrorCode.SYSTEM_EXCEPTION.getCode() + " msg" + ErrorCode.SYSTEM_EXCEPTION.getMsg());
			return result;
		}

		OrderDO domain = getDomain(entity);
		result.setModel(ResultDO.FIRST_MODEL_KEY, domain);

		return result;
	}

	@Override
	public ResultDO queryCellCore(String rechargeNumber) {
		ResultDO result = new ResultSupport();
		if(StringUtils.isEmpty(rechargeNumber)){
			result.setSuccess(false);
			result.setErrorCode(ErrorCode.PARAM_GET_ERROR);
			logger.info("error code：" + ErrorCode.PARAM_GET_ERROR.getCode() + " msg" + ErrorCode.PARAM_GET_ERROR.getMsg());
			return result;
		}
		QcellcoreEntity entity = null;
		try {
			entity = qcellcoreMapper.selectOne(Wrappers.<QcellcoreEntity>lambdaQuery().eq(QcellcoreEntity::getPhoneNo, rechargeNumber.substring(0,7)));
		} catch(Exception e) {
			result.setSuccess(false);
			result.setErrorCode(ErrorCode.SYSTEM_EXCEPTION);
			logger.info("error code：" + ErrorCode.SYSTEM_EXCEPTION.getCode() + " msg" + ErrorCode.SYSTEM_EXCEPTION.getMsg());
			return result;
		}
		QCellCoreDO domain = new QCellCoreDO();
		domain = BeanUtilsExtends.copyProperties(domain, entity) ? domain : null;
		result.setModel(ResultDO.FIRST_MODEL_KEY, domain);
		return result;
	}

	@Override
	@Transactional(propagation= Propagation.REQUIRED, rollbackFor= Exception.class)
	public ResultDO orderRefund(OrderDO domain) {
		OrderEntity entity = new OrderEntity();
		ResultDO result = new ResultSupport();
		try {
			entity = baseMapper.selectById(domain.getId());
		} catch(Exception e) {
			result.setSuccess(false);
			result.setErrorCode(ErrorCode.SYSTEM_EXCEPTION);
			return result;
		}
		if(entity.getStatus() != Constant.RECHARGE_ORDER_STATUS_3){
			result.setSuccess(false);
			result.setErrorCode(ErrorCode.ORDER_REFUND_ERROR);
			return result;
		}
		//判断订单是否已经退款
		if(StringUtils.isNotEmpty(entity.getRefundNo())){
			result.setSuccess(false);
			result.setErrorCode(ErrorCode.ORDER_REFUND_fFAILED_ERROR);
			return result;
		}
		RefundDO refund = new RefundDO();
		try {
			refund.setMerchantNo(domain.getMerchantNo());
			refund.setMerchantId(domain.getMerchantId());
			refund.setGoodsTitle(domain.getTitle());
			refund.setMerchantName(domain.getMerchantName());
			refund.setAmount(Double.valueOf(String.valueOf(ArithUtils.mul(Double.parseDouble(String.valueOf(domain.getAmount())), Double.parseDouble(String.valueOf(domain.getAgentDiscount()))))).longValue());
			refund.setType(Constant.REFUND_TYPE_MANUAL);
			refund.setGoodsTitle(domain.getGoodsName());
			result = refundService.submit(refund);
		} catch(Exception e) {
			result.setSuccess(false);
			result.setErrorCode(ErrorCode.ORDER_REFUND_fFAILED_ERROR);
			TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
			return result;
		}
		if(!result.isSuccess()){
			result.setSuccess(false);
			result.setErrorCode(ErrorCode.ORDER_REFUND_fFAILED_ERROR);
			TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
			return result;
		}
		refund = (RefundDO) result.getModel(ResultDO.FIRST_MODEL_KEY);

		boolean flog = false;
		//修改供货单的状态
		ProviderOrderEntity providerOrderEntity = new ProviderOrderEntity();
		providerOrderEntity.setStatus(Constant.PROVIDER_ORDER_STATUS_fail);
		providerOrderEntity.setRemark("成功未到账");
		try {
			flog = providerOrderService.update(
					providerOrderEntity,
					Wrappers.<ProviderOrderEntity>lambdaQuery()
							.eq(ProviderOrderEntity::getOrderNo, entity.getOrderNo())
							.eq(ProviderOrderEntity::getProviderId, entity.getProviderId())
							.eq(ProviderOrderEntity::getStatus, Constant.PROVIDER_ORDER_STATUS_2)
			);
		} catch(Exception e) {
			result.setSuccess(false);
			result.setErrorCode(ErrorCode.SYSTEM_EXCEPTION);
			TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
			return result;
		}
		if(flog){
			int count = 0;
			//修改订单中的退款单号
			entity = new OrderEntity();
			entity.setId(domain.getId());
			entity.setRefundNo(refund.getRefundNo());
			entity.setStatus(Constant.RECHARGE_ORDER_STATUS_4);
			entity.setProviderCallbackInfo("成功未到账");
			try {
				count = baseMapper.updateById(entity);
			} catch(Exception e) {
				result.setSuccess(false);
				result.setErrorCode(ErrorCode.SYSTEM_EXCEPTION);
				TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
				return result;
			}
			if(count <= 0){
				result.setSuccess(false);
				result.setErrorCode(ErrorCode.ORDER_REFUND_fFAILED_ERROR);
				TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
				return result;
			}
		}
		return result;
	}

	@Override
	@Transactional(propagation= Propagation.REQUIRED, rollbackFor= Exception.class)
	public ResultDO callBack(OrderDO domain) {

		ResultDO result = new ResultSupport();

		int code = 500;
		String message = "";
		if(domain.getStatus() == Constant.RECHARGE_ORDER_STATUS_3){
			code = 0;
		}
		if(domain.getStatus() == Constant.RECHARGE_ORDER_STATUS_4){
			code = ErrorCode.API_ORDER_PROVIDER_FAIL.getCode();
			message = ErrorCode.API_ORDER_PROVIDER_FAIL.getMsg();
		}
		//查询代理商的回调地址
		result = merchantService.get(domain.getMerchantId());
		if(!result.isSuccess()){
			return result;
		}
		int count = 0;
		try {
			OrderEntity entity = new OrderEntity();
			entity.setId(domain.getId());
			entity.setMerchantCallbackStatus(Constant.MERCHANT_CALL_STATUS_0);
			count = baseMapper.updateById(entity);
		} catch (Exception e) {
			result.setSuccess(false);
			result.setErrorCode(ErrorCode.SYSTEM_EXCEPTION);
			logger.info("error code：" + ErrorCode.SYSTEM_EXCEPTION.getCode() + " msg" + ErrorCode.SYSTEM_EXCEPTION.getMsg());
			TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
			return result;
		}
		if(count >0){
			MerchantDO merchantDO = (MerchantDO) result.getModel(ResultDO.FIRST_MODEL_KEY);
			result = merchantService.callback(domain.getMerchantSerialNumber(), domain.getOrderNo(), domain.getRechargeNumber(), domain.getVoucherNo(), code, message, merchantDO.getCallback());
			if(!result.isSuccess()){
				logger.error("回调失败：" + result.getErrorCode().getCode() + " msg" + result.getErrorCode().getMsg());
				TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
				return result;
			}
		}
		return result;
	}

	@Override
	public ResultDO callBackBatch(OrderDO domain) {
		ResultDO result = new ResultSupport();
		if(domain.getBatchOrderId() == null || domain.getBatchOrderId().length <=0){
			return result;
		}

		List<String> orderIds = Stream.of(domain.getBatchOrderId()).collect(Collectors.toList());

		List<OrderEntity> list = null;

		try {
			list = baseMapper.selectBatchIds(orderIds);
		} catch (Exception e) {
			result.setSuccess(false);
			result.setErrorCode(ErrorCode.SYSTEM_EXCEPTION);
			logger.info("error code：" + ErrorCode.SYSTEM_EXCEPTION.getCode() + " msg" + ErrorCode.SYSTEM_EXCEPTION.getMsg());
			return result;
		}
		if(list != null && list.size() > 0){
			list.stream().forEach( item -> {
				this.callBack(getDomain(item));
			});
		}
		return result;
	}

	@Override
	public ResultDO getByProviderOrderSerialNo(String outTradeNo) {
		ResultDO result = new ResultSupport();
		OrderEntity entity = null;

		try {
			entity = this.baseMapper.selectOne(Wrappers.<OrderEntity>lambdaQuery().eq(OrderEntity::getProviderSerialNumber,outTradeNo));
		} catch(Exception e) {
			result.setSuccess(false);
			result.setErrorCode(ErrorCode.SYSTEM_EXCEPTION);
			logger.info("error code：" + ErrorCode.SYSTEM_EXCEPTION.getCode() + " msg" + ErrorCode.SYSTEM_EXCEPTION.getMsg());
			return result;
		}

		OrderDO domain = getDomain(entity);

		result.setModel(ResultDO.FIRST_MODEL_KEY, domain);

		return result;
	}

	@Override
	public ResultDO updateBatchOrderById(List<OrderDO> orderList) {
		ResultDO result = new ResultSupport();
		if(orderList == null || orderList.size() <=0){
			result.setSuccess(false);
			result.setErrorCode(ErrorCode.SYSTEM_EXCEPTION);
			logger.info("error code：" + ErrorCode.SYSTEM_EXCEPTION.getCode() + " msg" + ErrorCode.SYSTEM_EXCEPTION.getMsg());
			return result;
		}
		List<OrderEntity> order = new ArrayList<>();
		orderList.stream().forEach( item -> {
			OrderEntity entity = new OrderEntity();
			entity.setId(item.getId());
			entity.setStatus(item.getStatus());
			entity.setRefundNo(item.getRefundNo());
			order.add(entity);
		});
		boolean flog = false;
		try {
			flog = this.updateBatchById(order);
		} catch(Exception e) {
			result.setSuccess(false);
			result.setErrorCode(ErrorCode.SYSTEM_EXCEPTION);
			logger.info("error code：" + ErrorCode.SYSTEM_EXCEPTION.getCode() + " msg" + ErrorCode.SYSTEM_EXCEPTION.getMsg());
			return result;
		}
		if(!flog){
			result.setSuccess(false);
			result.setErrorCode(ErrorCode.SYSTEM_EXCEPTION);
			logger.info("error code：" + ErrorCode.SYSTEM_EXCEPTION.getCode() + " msg" + ErrorCode.SYSTEM_EXCEPTION.getMsg());
			return result;
		}
		return result;
	}

	@Override
	public ResultDO findList(OrderQueryDO query) {
		OrderEntity entity = new OrderEntity();
		String[] queryData = query.getCreateDate();
		query.setCreateDate(null);
		ResultDO result = BeanUtilsExtends.copy(entity, query);
		if (!result.isSuccess()) {
			logger.info("error code：" + result.getErrorCode().getCode() + " msg" + result.getErrorCode().getMsg());
			return result;
		}
		entity.setProcessTime(null);
		entity.setMerchantName(null);
		QueryWrapper<OrderEntity> wrapper = new QueryWrapper<OrderEntity>(entity);
		if(queryData != null && queryData.length == 2){
			wrapper.lambda().between(OrderEntity::getCreateDate, queryData[0], queryData[1]);
		}
		if(query.getProcessTime() != null && query.getProcessTime().length == 2){
			if(query.getProcessTime()[0] != null && query.getProcessTime()[1] != null){
				wrapper.lambda().between(OrderEntity::getProcessTime, query.getProcessTime()[0] * 1000, query.getProcessTime()[1] * 1000);
			}
		}
		if(StringUtils.isNotEmpty(query.getMerchantName())){
			wrapper.lambda().like(OrderEntity::getMerchantName, query.getMerchantName());
		}
		if(StringUtils.isNotEmpty(query.getGoodsName())){
			wrapper.lambda().like(OrderEntity::getTitle, query.getGoodsName());
		}
		if(query.getServiceProvider() != null){
			wrapper.lambda().like(OrderEntity::getServiceProvider, query.getServiceProvider());
		}
		if(query.getMerchantIds() != null && query.getMerchantIds().length >0){
			if(query.isQueryMerchantType()){
				Stream.of(query.getMerchantIds()).forEach(merchantId -> {
					wrapper.lambda().ne(OrderEntity::getMerchantId, merchantId);
				});
			} else {
				wrapper.lambda().and( newWrapper -> {
					newWrapper.and( merchantIdWrapper -> {
						Stream.of(query.getMerchantIds()).forEach(merchantId -> {
							merchantIdWrapper.or(itemWrapper -> itemWrapper.eq(OrderEntity::getMerchantId, merchantId));
						});
					});
				});
			}
		}
		if(StringUtils.isNotEmpty(query.getMerchantId())){
			wrapper.lambda().eq(OrderEntity::getMerchantId, query.getMerchantId());
		}
		if(query.getStatus() != null && query.getStatus() == Constant.RECHARGE_ORDER_STATUS_5){
			wrapper.lambda().orderByDesc(OrderEntity::getProcessTime, OrderEntity::getCreateDate);
		} else {
			wrapper.lambda().orderByDesc(OrderEntity::getCreateDate);
		}
		List<OrderEntity> list = null;
		try {
			list = baseMapper.selectList(wrapper);
		} catch (Exception e) {
			result.setSuccess(false);
			result.setErrorCode(ErrorCode.SYSTEM_EXCEPTION);
			logger.info("error code：" + ErrorCode.SYSTEM_EXCEPTION.getCode() + " msg" + ErrorCode.SYSTEM_EXCEPTION.getMsg());
			return result;
		}
		List<OrderDO> doList = getDomainList(list);

		result.setModel(ResultDO.FIRST_MODEL_KEY, doList);
		return result;
	}

	public ResultDO find(OrderQueryDO query) {
		OrderEntity entity = new OrderEntity();
		String[] queryData = query.getCreateDate();
		query.setCreateDate(null);
		ResultDO result = BeanUtilsExtends.copy(entity, query);
		if (!result.isSuccess()) {
			logger.info("error code：" + result.getErrorCode().getCode() + " msg" + result.getErrorCode().getMsg());
			return result;
		}
		entity.setProcessTime(null);
		entity.setMerchantName(null);
		QueryWrapper<OrderEntity> wrapper = new QueryWrapper<OrderEntity>(entity);
		Page<OrderEntity> page = new Page<>(query.getCurrentPage(),query.getPageSize());
		if(queryData != null && queryData.length == 2){
			wrapper.lambda().between(OrderEntity::getCreateDate, queryData[0], queryData[1]);
		}
		if(query.getProcessTime() != null && query.getProcessTime().length == 2){
			if(query.getProcessTime()[0] != null && query.getProcessTime()[1] != null){
				wrapper.lambda().between(OrderEntity::getProcessTime, query.getProcessTime()[0] * 1000, query.getProcessTime()[1] * 1000);
			}
		}
		if(StringUtils.isNotEmpty(query.getMerchantName())){
			wrapper.lambda().like(OrderEntity::getMerchantName, query.getMerchantName());
		}
		if(StringUtils.isNotEmpty(query.getGoodsName())){
			wrapper.lambda().like(OrderEntity::getTitle, query.getGoodsName());
		}

		if(query.getServiceProvider() != null){
			wrapper.lambda().like(OrderEntity::getServiceProvider, query.getServiceProvider());
		}
		if(query.getMerchantIds() != null && query.getMerchantIds().length >0){
			if(query.isQueryMerchantType()){
				Stream.of(query.getMerchantIds()).forEach(merchantId -> {
					wrapper.lambda().ne(OrderEntity::getMerchantId, merchantId);
				});
			} else {
				wrapper.lambda().and( newWrapper -> {
					newWrapper.and( merchantIdWrapper -> {
						Stream.of(query.getMerchantIds()).forEach(merchantId -> {
							merchantIdWrapper.or(itemWrapper -> itemWrapper.eq(OrderEntity::getMerchantId, merchantId));
						});
					});
				});
			}
		}

		if(StringUtils.isNotEmpty(query.getMerchantId())){
			wrapper.lambda().eq(OrderEntity::getMerchantId, query.getMerchantId());
		}

		if(query.getStatus() != null && query.getStatus() == Constant.RECHARGE_ORDER_STATUS_5){
			wrapper.lambda().orderByDesc(OrderEntity::getProcessTime, OrderEntity::getCreateDate);
		} else {
			wrapper.lambda().orderByDesc(OrderEntity::getCreateDate);
		}

		IPage<OrderEntity> iPage = null;

		try {
			iPage = baseMapper.selectPage(page, wrapper);
		} catch (Exception e) {
			result.setSuccess(false);
			result.setErrorCode(ErrorCode.SYSTEM_EXCEPTION);
			logger.info("error code：" + ErrorCode.SYSTEM_EXCEPTION.getCode() + " msg" + ErrorCode.SYSTEM_EXCEPTION.getMsg());
			return result;
		}
		List<OrderDO> doList = getDomainList(iPage.getRecords());
		PageDO<OrderDO> pageDO = new PageDO<>();

		pageDO.setCurrentPage(iPage.getCurrent());
		pageDO.setPageCount(iPage.getPages());
		pageDO.setPageSize(iPage.getSize());
		pageDO.setRowCount(iPage.getTotal());
		pageDO.setData(doList);

		result.setModel(ResultDO.FIRST_MODEL_KEY, pageDO);
		return result;
	}

	public ResultDO reportorder(OrderQueryDO query) {
		OrderEntity entity = new OrderEntity();
		String[] queryData = query.getCreateDate();
		query.setCreateDate(null);
		ResultDO result = BeanUtilsExtends.copy(entity, query);
		if (!result.isSuccess()) {
			logger.info("error code：" + result.getErrorCode().getCode() + " msg" + result.getErrorCode().getMsg());
			return result;
		}
		entity.setProcessTime(null);
		entity.setMerchantName(null);
		QueryWrapper<OrderEntity> wrapper = new QueryWrapper<OrderEntity>(entity);
		Page page = new Page<>(query.getCurrentPage(),query.getPageSize());
		if(queryData != null && queryData.length == 2){
			wrapper.lambda().between(OrderEntity::getCreateDate, queryData[0], queryData[1]);
		}
		if(query.getProcessTime() != null && query.getProcessTime().length == 2){
			if(query.getProcessTime()[0] != null && query.getProcessTime()[1] != null){
				wrapper.lambda().between(OrderEntity::getProcessTime, query.getProcessTime()[0] * 1000, query.getProcessTime()[1] * 1000);
			}
		}
		if(StringUtils.isNotEmpty(query.getMerchantName())){
			wrapper.lambda().like(OrderEntity::getMerchantName, query.getMerchantName());
		}
		if(StringUtils.isNotEmpty(query.getGoodsName())){
			wrapper.lambda().like(OrderEntity::getTitle, query.getGoodsName());
		}
		if(query.getServiceProvider() != null){
			wrapper.lambda().like(OrderEntity::getServiceProvider, query.getServiceProvider());
		}
		if(query.getMerchantIds() != null && query.getMerchantIds().length >0){
			if(query.isQueryMerchantType()){
				Stream.of(query.getMerchantIds()).forEach(merchantId -> {
					wrapper.lambda().ne(OrderEntity::getMerchantId, merchantId);
				});
			} else {
				wrapper.lambda().and( newWrapper -> {
					newWrapper.and( merchantIdWrapper -> {
						Stream.of(query.getMerchantIds()).forEach(merchantId -> {
							merchantIdWrapper.or(itemWrapper -> itemWrapper.eq(OrderEntity::getMerchantId, merchantId));
						});
					});
				});
			}
		}

		if(StringUtils.isNotEmpty(query.getMerchantId())){
			wrapper.lambda().eq(OrderEntity::getMerchantId, query.getMerchantId());
		}

		ResultDO sizeResult = rechargeService.getHandlerOrderSize();
		int handleNumber=0;
		if(sizeResult.getModel(ResultDO.FIRST_MODEL_KEY)!=null){
			handleNumber= (int)sizeResult.getModel(ResultDO.FIRST_MODEL_KEY);
		}

		wrapper.select(
				"sum(case when status = 5 then 1 else 0 end) as processNumber",
				"sum(case when status = 3 then 1 else 0 end) as successNumber",
				"sum(case when status = 4 then 1 else 0 end) as failNumber",
				"sum(case when status = 7 then 1 else 0 end) as unconfirmedNumber",
				"count(1) as totalNumber",
				"sum(case when status = 3 then (amount*(cast(agent_discount*10000 as SIGNED)))/10000 else 0 end) as sale" ,
				"sum(case when status = 3 then (amount*(cast(cost_discount*10000 as SIGNED)))/10000 else 0 end) as cost"
		);

		List<OrderEntity> list = null;
		try {
			list = baseMapper.selectList(wrapper);
		} catch (Exception e) {
			e.printStackTrace();
			result.setSuccess(false);
			result.setErrorCode(ErrorCode.SYSTEM_EXCEPTION);
			logger.info("error code：" + ErrorCode.SYSTEM_EXCEPTION.getCode() + " msg" + ErrorCode.SYSTEM_EXCEPTION.getMsg());
			return result;
		}
		List<OrderDO> doList = getDomainList(list);
		if(doList!=null&&doList.size()>0){
			OrderDO orderdo = doList.get(0);
			orderdo.setHandleNumber(handleNumber);
			orderdo.setProcessNumber(orderdo.getProcessNumber()==null?0:orderdo.getProcessNumber());
			orderdo.setSuccessNumber(orderdo.getSuccessNumber()==null?0:orderdo.getSuccessNumber());
			orderdo.setFailNumber(orderdo.getFailNumber()==null?0:orderdo.getFailNumber());
			orderdo.setUnconfirmedNumber(orderdo.getUnconfirmedNumber()==null?0:orderdo.getUnconfirmedNumber());
			orderdo.setSale(orderdo.getSale()==null?0.0:orderdo.getSale());
			orderdo.setCost(orderdo.getCost()==null?0.0:orderdo.getCost());
			doList.set(0,orderdo);
		}

		PageDO<OrderDO> pageDO = new PageDO<>();

		pageDO.setData(doList);

		result.setModel(ResultDO.FIRST_MODEL_KEY, pageDO);
		return result;
	}

	private List<OrderDO> getDomainList(List<OrderEntity> list) {
		//创建一个名为dolist的房源do类型的 list集合
		List<OrderDO> doList = new ArrayList<>();

		//判断传入的list的集合的size是否大于0
		if(list.size() > 0) {
			//大于0是，遍历list，创建do类型的对象 调用getdomain方法
			for(OrderEntity entity : list) {

				OrderDO domain = this.getDomain(entity);

				//判断得到的domain 是否为空 不为空 就往dolist集合里面添加domian 为空就返回空
				if(domain == null) {
					return null;
				}
				doList.add(domain);
			}
		} else {
			return null;
		}
		return doList;
	}

	private OrderDO getDomain(OrderEntity entity) {

		//判断房源对象是否为空，为空就返回 空，不为空就进行下面的代码
		if(entity == null) return null;
		OrderDO domain = new OrderDO();

		domain = BeanUtilsExtends.copyProperties(domain, entity) ? domain : null;

		//判断拷贝数据到Dto对象是否成功，如果成功则返回domian，如果不成功就返回空
		return domain;
	}

	private OrderDO getDomain(OrderCommitEntity entity) {

		//判断房源对象是否为空，为空就返回 空，不为空就进行下面的代码
		if(entity == null) return null;
		OrderDO domain = new OrderDO();

		domain = BeanUtilsExtends.copyProperties(domain, entity) ? domain : null;

		//判断拷贝数据到Dto对象是否成功，如果成功则返回domian，如果不成功就返回空
		return domain;
	}


}

